package dashboard_util

import (
	template_funcs "app/app_src/framework/template/funcs"
	template_wrapper "app/app_src/framework/template/wrapper"
	"encoding/xml"
	"io/fs"
	"strings"
	"text/template"
)

type Menus struct {
	Menus []Menu `xml:"menu"`
}

// 菜单
type Menu struct {
	// 菜单代码
	Code string `xml:"code"`
	// 菜单名称
	Name string `xml:"name"`
	// 菜单路径
	Path string `xml:"path"`
	// 菜单图标
	Icon string `xml:"icon"`

	// 子菜单
	Submenus *Submenus `xml:"submenus"`
}

// 子菜单
type Submenus struct {
	Menus []Menu `xml:"menu"`
}

const _MAP_KEY_MENU_CODE = "code"
const _MAP_KEY_MENU_NAME = "name"
const _MAP_KEY_MENU_PATH = "path"
const _MAP_KEY_MENU_ICON = "icon"
const _MAP_KEY_MENU_CHILDREN = "children"

// 解析菜单 XML 格式
func ParseMenuXML(fs fs.ReadFileFS, path string) []map[string]any {
	result := []map[string]any{}

	// 读取文件
	xmlBytes, err := fs.ReadFile(path)
	if err != nil {
		panic(err)
	}

	// 本地化菜单内容
	xmlStr := LocalizeMenuContent(string(xmlBytes))

	xmlRoot := Menus{}
	// 解析 XML 格式
	err = xml.Unmarshal([]byte(xmlStr), &xmlRoot)
	if err != nil {
		panic(err)
	}

	menus := xmlRoot.Menus
	if menus == nil {
		return result
	}

	// 创建菜单的映射
	for index := range menus {
		result = append(result, CreateMenuMap(&menus[index]))
	}

	return result
}

// 本地化菜单内容
func LocalizeMenuContent(content string) string {
	funcMap := template.FuncMap{"t": template_funcs.NewHtmI18nFunc()}
	parser := template_wrapper.NewTemplateParser(template_wrapper.TEMPLATE_TYPE_HTML, funcMap)
	parser.LeftDelim = "${"
	parser.RightDelim = "}"

	template := parser.ParseTemplate("", content)
	var writer strings.Builder
	template.RenderTemplate(&writer, nil)

	return writer.String()
}

// 创建菜单的映射
func CreateMenuMap(menu *Menu) map[string]any {
	menuMap := map[string]any{}

	menuMap[_MAP_KEY_MENU_CODE] = strings.Trim(menu.Code, " ")
	menuMap[_MAP_KEY_MENU_NAME] = strings.Trim(menu.Name, " ")
	menuMap[_MAP_KEY_MENU_PATH] = strings.Trim(menu.Path, " ")
	menuMap[_MAP_KEY_MENU_ICON] = strings.Trim(menu.Icon, " ")

	submenus := menu.Submenus
	if submenus == nil {
		return menuMap
	}

	menus := submenus.Menus
	if menus == nil {
		return menuMap
	}

	submenuMaps := []map[string]any{}
	// 创建子菜单的映射
	for index := range menus {
		submenuMaps = append(submenuMaps, CreateMenuMap(&menus[index]))
	}
	menuMap[_MAP_KEY_MENU_CHILDREN] = submenuMaps

	return menuMap
}
